home *** CD-ROM | disk | FTP | other *** search
/ The World's Largest Collection of Windows Software / The World's Largest Collection of Windows Software - Disc 1.iso / connect / _j2 / wvnsc926 / wvscreen.c < prev    next >
C/C++ Source or Header  |  1994-09-21  |  25KB  |  895 lines

  1.  
  2. /*
  3.  *
  4.  * $Id: wvscreen.c 1.14 1994/09/16 00:52:27 jcooper Exp $
  5.  * $Log: wvscreen.c $
  6.  * Revision 1.14  1994/09/16  00:52:27  jcooper
  7.  * cleanup for 92.6
  8.  *
  9.  * Revision 1.13  1994/08/24  18:00:29  jcooper
  10.  * misc encoding/decoding changes
  11.  *
  12.  * Revision 1.12  1994/07/27  21:12:19  gardnerd
  13.  * copy to clipboard
  14.  *
  15.  * Revision 1.11  1994/07/12  19:51:26  cnolan
  16.  * win32ism
  17.  *
  18.  * Revision 1.10  1994/06/01  19:08:20  gardnerd
  19.  * horizontal scrolling support
  20.  *
  21.  * Revision 1.9  1994/02/24  21:34:08  jcoop
  22.  * jcoop changes
  23.  *
  24.  * Revision 1.8  1994/02/09  18:01:08  cnolan
  25.  * cnolan 90.2 changes
  26.  *
  27.  * Revision 1.7  1994/01/12  19:27:32  mrr
  28.  * mrr mods 4
  29.  *
  30.  * Revision 1.6  1993/12/08  01:28:01  rushing
  31.  * new version box and cr lf consistency
  32.  *
  33.  * Revision 1.5  1993/07/06  20:53:23  rushing
  34.  * type fixed
  35.  *
  36.  * Revision 1.4  1993/07/06  20:52:28  cnolan
  37.  * win32 changes
  38.  *
  39.  * Revision 1.3  1993/06/28  17:51:39  rushing
  40.  * fixed compiler warnings
  41.  *
  42.  * Revision 1.2  1993/05/26  18:30:40  rushing
  43.  * fixed page down bug (GPE when #arts < what can fit in window)
  44.  *
  45.  * Revision 1.1  1993/02/16  20:54:22  rushing
  46.  * Initial revision
  47.  *
  48.  *
  49.  */
  50.  
  51. /*-- First Line of WVSCREEN.C -- Contains Screen-related functions.  */
  52. #include <windows.h>
  53. #include <windowsx.h>
  54. #include "wvglob.h"
  55. #include "winvn.h"
  56. #pragma hdrstop
  57.  
  58. /*--- function ScreenDown ----------------------------------------------
  59.  *
  60.  *  Advance a pointer "nLines" lines through the textlines.
  61.  *  However, do not go so far that less than LinesOnScreen lines
  62.  *  are left past the pointer.
  63.  *
  64.  *  This is used to implement "PageDown" and "LineDown" functions.
  65.  *
  66.  *    Entry    nLines         Number of lines to move the pointer.
  67.  *             LinesOnScreen  is the number of lines on the screen.
  68.  *             BlockPtr       Pointer to block containing line.
  69.  *             LinePtr        Pointer to the given line.
  70.  *
  71.  *    Exit     BlockPtr and LinePtr (may) have been moved to a new line.
  72.  *             LinesAdvanced  is the number of lines actually moved--can be
  73.  *                            less than nLines if we hit the top of the
  74.  *                            last screen.
  75.  */
  76. void
  77. ScreenDown (nLines, LinesOnScreen, BlockPtr, LinePtr, LinesAdvanced)
  78.      int nLines;
  79.      int LinesOnScreen;
  80.      TypBlock far **BlockPtr;
  81.      TypLine far **LinePtr;
  82.      int *LinesAdvanced;
  83. {
  84.   TypBlock far *MyBlock = *BlockPtr;
  85.   TypLine far *MyLine = *LinePtr;
  86.   int LinesGone;
  87.   int TestAdvance;
  88.   HANDLE hBlock, hBlockGarbage;
  89.   unsigned int Offset, OffsetGarbage;
  90.   TypLineID LineIDGarbage, MyLineID;
  91.  
  92.   /* Skip forward nLines, plus one screen's worth, just to see      */
  93.   /* if there are enough lines ahead of us in the document.         */
  94.  
  95.   PtrToOffset (MyBlock, MyLine, &hBlock, &Offset, &MyLineID);
  96.   TestAdvance = nLines + LinesOnScreen - 1;
  97.   for (LinesGone = TestAdvance; LinesGone ;) {
  98.       if(!NextLine (&MyBlock, &MyLine)) break;
  99.       /* Count only active lines. */
  100.       if(MyLine->active) LinesGone--;
  101.   }
  102.   UnlockLine (MyBlock, MyLine, &hBlockGarbage, &OffsetGarbage, &LineIDGarbage);
  103.  
  104.   nLines -= LinesGone;
  105.   if (nLines < 0)
  106.     nLines = 0;
  107.   *LinesAdvanced = nLines;
  108.  
  109.   LockLine (hBlock, Offset, MyLineID, &MyBlock, &MyLine);
  110.   while (nLines)
  111.     {
  112.       NextLine (BlockPtr, LinePtr);
  113.       if((*LinePtr)->active) nLines--;
  114.     }
  115. }
  116.  
  117. /*--- function ScreenUp ----------------------------------------------
  118.  *
  119.  *  Back up a pointer "nLines" lines through the textlines.
  120.  *  However, do not go past the beginning of the document.
  121.  *
  122.  *  This is used to implement "PageUp" and "LineUp" functions.
  123.  *
  124.  *    Entry    nLines         Number of lines to move the pointer.
  125.  *             BlockPtr       Pointer to block containing line.
  126.  *             LinePtr        Pointer to the given line.
  127.  *
  128.  *    Exit     BlockPtr and LinePtr (may) have been moved to a new line.
  129.  *             LinesBackedUp  is the number of lines actually moved--can be
  130.  *                            less than nLines if we hit beginning of doc.
  131.  */
  132. void
  133. ScreenUp (nLines, BlockPtr, LinePtr, LinesBackedUp)
  134.      int nLines;
  135.      TypBlock far **BlockPtr;
  136.      TypLine far **LinePtr;
  137.      int *LinesBackedUp;
  138. {
  139.   *LinesBackedUp = 0;
  140.  
  141.   while (nLines && PrevLine (BlockPtr, LinePtr))
  142.     {          
  143.       if((*LinePtr)->active) {
  144.          nLines--;
  145.          (*LinesBackedUp)++;
  146.       }
  147.     }
  148. }
  149.  
  150. /*--- function NewScrollIt ----------------------------------------------
  151.  *
  152.  *  Perform a scrolling action.
  153.  *
  154.  *    Entry    Document points to a document
  155.  *             wParam   is the wParam argument given from a WM_VSCROLL
  156.  *                      window message.  (One of the SB_ symbols.)
  157.  *             lParam   is the lParam argument.
  158.  *
  159.  *   except in WIN32 ...
  160.  *
  161.  *          wParam   LOWORD: SB_code, HIWORD: position.
  162.  */
  163. void
  164. NewScrollIt (Document, wParam, lParam)
  165.      TypDoc *Document;
  166.      WPARAM wParam;
  167.      LPARAM lParam;
  168. {
  169.   int LinesGone;
  170.   unsigned int LineOrd;
  171.   RECT Rect;
  172.   int window_lineheight, window_topspace;
  173.  
  174.   if (Document->DocType == DOCTYPE_ARTICLE)
  175.   {
  176.    window_lineheight = ArtLineHeight;
  177.    window_topspace = ArtTopSpace; 
  178.   }
  179.   else
  180.   {
  181.    window_lineheight = LineHeight;
  182.    window_topspace = TopSpace;
  183.   }
  184.  
  185.   switch (LOWORD(wParam))
  186.     {
  187.     case SB_LINEUP:
  188.       /* Move up a line by scrolling the window down one line     */
  189.       /* and introducing 1 new line at the top.                   */
  190.  
  191.    if (Document->TopLineOrd > 0) {
  192.       LinesGone = 1;
  193.     }
  194.     else LinesGone = 0;
  195.  
  196.     doscrollup:;
  197.       if (LinesGone)
  198.    {
  199.      Rect.left = 0;
  200.      Rect.right = Document->ScXWidth;
  201.      Document->TopLineOrd -= LinesGone;
  202.  
  203.      ScrollWindow (Document->hDocWnd, 0, LinesGone * window_lineheight, NULL, NULL);
  204.  
  205.      Rect.top = window_topspace;
  206.      Rect.bottom = window_topspace + LinesGone * window_lineheight;
  207.  
  208.      InvalidateRect (Document->hDocWnd, &Rect, FALSE);
  209.  
  210.      /* Make sure garbage at bottom is erased in WM_PAINT processing */
  211.      Rect.top = window_topspace + Document->ScYLines * window_lineheight;
  212.      Rect.bottom = Document->ScYHeight;
  213.      InvalidateRect (Document->hDocWnd, &Rect, FALSE);
  214.    }
  215.       break;
  216.  
  217.     case SB_LINEDOWN:
  218.       /* Should change TotalLines below to ActiveLines for 
  219.        * suppression of already-read articles, but it's not that simple.
  220.        *  /mrr
  221.        */
  222.    if (Document->TopLineOrd < (Document->ActiveLines - Document->ScYLines)) {
  223.       LinesGone = 1;
  224.     }
  225.    else LinesGone = 0;
  226.  
  227.     doscrolldown:;
  228.       if (LinesGone)
  229.    {
  230.      Document->TopLineOrd += LinesGone;
  231.      Rect.left = 0;
  232.      Rect.right = Document->ScXWidth;
  233.      ScrollWindow (Document->hDocWnd, 0, -LinesGone * window_lineheight, NULL, NULL);
  234.      Rect.top = window_topspace + (Document->ScYLines - LinesGone) * window_lineheight;
  235.      Rect.bottom = Document->ScYHeight;
  236.      InvalidateRect (Document->hDocWnd, &Rect, FALSE);
  237.      /* Make sure garbage at top is erased in WM_PAINT processing */
  238.      Rect.top = 0;
  239.      Rect.bottom = window_topspace;
  240.      InvalidateRect (Document->hDocWnd, &Rect, FALSE);
  241.    }
  242.       break;
  243.  
  244.     case SB_PAGEUP:
  245. /*      LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr); */
  246. /*      ScreenUp (Document->ScYLines - 1, &BlockPtr, &LinePtr, &LinesGone); */
  247.       LinesGone= Document->TopLineOrd - (Document->ScYLines - 1);
  248.       if (LinesGone > 0) {
  249.    LinesGone = Document->ScYLines - 1;
  250.       }
  251.    else {
  252.    LinesGone = Document->TopLineOrd;
  253.    }
  254.  
  255.       Document->TopLineOrd -= LinesGone;
  256.       InvalidateRect (Document->hDocWnd, NULL, FALSE);
  257.       break;
  258.  
  259.  case SB_PAGEDOWN:
  260.  
  261.    if (Document->ActiveLines > Document->ScYLines) { /* do we even need to scroll? */
  262.      if ((Document->ActiveLines -
  263.      (Document->TopLineOrd + Document->ScYLines)) > Document->ScYLines)
  264.        LinesGone = Document->ScYLines - 1;
  265.      else
  266.        LinesGone = Document->ActiveLines - (Document->TopLineOrd + Document->ScYLines );
  267.  
  268.      Document->TopLineOrd += LinesGone;
  269.      InvalidateRect (Document->hDocWnd, NULL, FALSE);
  270.    }
  271.    break;
  272.  
  273.  case SB_THUMBPOSITION:
  274. #ifdef WIN32
  275.        LineOrd = (int)HIWORD (wParam);
  276. #else
  277.        LineOrd = LOWORD (lParam);
  278. #endif
  279. /*       if (!FindLineOrd (Document, LineOrd, &BlockPtr, &LinePtr))
  280.    {
  281.      return;
  282.    }
  283. */
  284.     doposition:;
  285.       Document->TopLineOrd = LineOrd;
  286.       InvalidateRect (Document->hDocWnd, NULL, FALSE);
  287.       break;
  288.  
  289.     case SB_THUMBTRACK:
  290.  
  291. #ifdef WIN32
  292.        LineOrd = (int)HIWORD (wParam);
  293. #else
  294.        LineOrd = LOWORD (lParam);
  295. #endif
  296. /*      if (!FindLineOrd (Document, LineOrd, &BlockPtr, &LinePtr))
  297.    {
  298.      return;
  299.    }
  300. */
  301.       LinesGone = LineOrd - Document->TopLineOrd;
  302.       if (LinesGone > 0)
  303.    {
  304.      if (LinesGone >= (int) (Document->ScYLines - 1))
  305.        {
  306.          goto doposition;
  307.        }
  308.      else
  309.        {
  310.          goto doscrolldown;
  311.        }
  312.    }
  313.       else if (LinesGone < 0)
  314.    {
  315.      LinesGone = -LinesGone;
  316.      if (LinesGone >= (int) (Document->ScYLines - 1))
  317.        {
  318.          goto doposition;
  319.        }
  320.      else
  321.        {
  322.          goto doscrollup;
  323.        }
  324.    }
  325.  
  326.       break;
  327.  
  328.     default:
  329.       return;
  330.       break;
  331.     }
  332.  
  333. /*  UnlockLine (BlockPtr, LinePtr, &(Document->hCurTopScBlock),
  334.          &(Document->TopScOffset), &(Document->TopScLineID));
  335. */
  336.  
  337. }
  338. /*--- function ScrollIt ----------------------------------------------
  339.  *
  340.  *  Perform a scrolling action.
  341.  *
  342.  *    Entry    Document points to a document
  343.  *             wParam   is the wParam argument given from a WM_VSCROLL
  344.  *                      window message.  (One of the SB_ symbols.)
  345.  *             lParam   is the lParam argument.
  346.  */
  347. void
  348. ScrollIt (Document, wParam, lParam)
  349.      TypDoc *Document;
  350.      WPARAM wParam;
  351.      LPARAM lParam;
  352. {
  353.   TypBlock far *BlockPtr;
  354.   TypLine far *LinePtr;
  355.   int LinesGone;
  356.   unsigned int LineOrd;
  357.   RECT Rect;
  358.   int window_lineheight, window_topspace;
  359.   
  360.   if(Document->DocType == DOCTYPE_ARTICLE)
  361.   {
  362.     window_lineheight = ArtLineHeight;
  363.     window_topspace = ArtTopSpace;
  364.   }
  365.   else
  366.   {
  367.     window_lineheight = LineHeight;
  368.     window_topspace = TopSpace;
  369.   }  
  370.     
  371.   switch (LOWORD(wParam))
  372.     {
  373.     case SB_LINEUP:
  374.       /* Move up a line by scrolling the window down one line     */
  375.       /* and introducing 1 new line at the top.                   */
  376.       LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr); 
  377.       AdvanceToActive(&BlockPtr,&LinePtr);
  378.       ScreenUp (1, &BlockPtr, &LinePtr, &LinesGone);
  379.     doscrollup:;
  380.       if (LinesGone)
  381.    {
  382.      Rect.left = 0;
  383.      Rect.right = Document->ScXWidth;
  384.      Document->TopLineOrd -= LinesGone;
  385.      ScrollWindow (Document->hDocWnd, 0, LinesGone * (window_lineheight), NULL, NULL);
  386.  
  387.      Rect.top = window_topspace;
  388.      Rect.bottom = window_topspace + LinesGone * window_lineheight;
  389.  
  390.      InvalidateRect (Document->hDocWnd, &Rect, FALSE);
  391.      /* Make sure garbage at bottom is erased in WM_PAINT processing */
  392.      Rect.top = window_topspace + Document->ScYLines * window_lineheight;
  393.      Rect.bottom = Document->ScYHeight;
  394.      InvalidateRect (Document->hDocWnd, &Rect, FALSE);
  395.    }
  396.       break;
  397.  
  398.     case SB_LINEDOWN:
  399.       LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr);
  400.       AdvanceToActive(&BlockPtr,&LinePtr);
  401.       ScreenDown (1, Document->ScYLines, &BlockPtr, &LinePtr, &LinesGone);
  402.     doscrolldown:;
  403.       if (LinesGone)
  404.    {
  405.      Document->TopLineOrd += LinesGone;
  406.      Rect.left = 0;
  407.      Rect.right = Document->ScXWidth;
  408.      ScrollWindow (Document->hDocWnd, 0, -LinesGone * (window_lineheight), NULL, NULL);
  409.      Rect.top = window_topspace + (Document->ScYLines - LinesGone) * window_lineheight;
  410.      Rect.bottom = Document->ScYHeight;
  411.      InvalidateRect (Document->hDocWnd, &Rect, FALSE);
  412.      /* Make sure garbage at top is erased in WM_PAINT processing */
  413.      Rect.top = 0;
  414.      Rect.bottom = window_topspace;
  415.      InvalidateRect (Document->hDocWnd, &Rect, FALSE);
  416.    }
  417.       break;
  418.  
  419.     case SB_PAGEUP:
  420.       LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr);
  421.       AdvanceToActive(&BlockPtr,&LinePtr);
  422.       ScreenUp (Document->ScYLines - 1, &BlockPtr, &LinePtr, &LinesGone);
  423.       Document->TopLineOrd -= LinesGone;
  424.       InvalidateRect (Document->hDocWnd, NULL, FALSE);
  425.       break;
  426.  
  427.     case SB_PAGEDOWN:
  428.       LockLine (Document->hCurTopScBlock, Document->TopScOffset, Document->TopScLineID, &BlockPtr, &LinePtr);
  429.       AdvanceToActive(&BlockPtr,&LinePtr);
  430.       ScreenDown (Document->ScYLines - 1, Document->ScYLines,
  431.         &BlockPtr, &LinePtr, &LinesGone);
  432.       Document->TopLineOrd += LinesGone;
  433.       InvalidateRect (Document->hDocWnd, NULL, FALSE);
  434.       break;
  435.  
  436.     case SB_THUMBPOSITION:
  437. #ifdef WIN32
  438.        LineOrd = (int)HIWORD (wParam);
  439. #else
  440.        LineOrd = LOWORD (lParam);
  441. #endif
  442.       if (!FindLineOrd (Document, LineOrd, &BlockPtr, &LinePtr))
  443.    {
  444.      return;
  445.    }
  446.     doposition:;
  447.       Document->TopLineOrd = LineOrd;
  448.       InvalidateRect (Document->hDocWnd, NULL, FALSE);
  449.       break;
  450.  
  451.     case SB_THUMBTRACK:
  452.                                                   
  453. #ifdef WIN32
  454.        LineOrd = (int)HIWORD (wParam);
  455. #else
  456.        LineOrd = LOWORD (lParam);
  457. #endif
  458.       if (!FindLineOrd (Document, LineOrd, &BlockPtr, &LinePtr))
  459.    {
  460.      return;
  461.    }
  462.       LinesGone = LineOrd - Document->TopLineOrd;
  463.       if (LinesGone > 0)
  464.    {
  465.      if (LinesGone >= (int) (Document->ScYLines - 1))
  466.        {
  467.          goto doposition;
  468.        }
  469.      else
  470.        {
  471.          goto doscrolldown;
  472.        }
  473.    }
  474.       else if (LinesGone < 0)
  475.    {
  476.      LinesGone = -LinesGone;
  477.      if (LinesGone >= (int) (Document->ScYLines - 1))
  478.        {
  479.          goto doposition;
  480.        }
  481.      else
  482.        {
  483.          goto doscrollup;
  484.        }
  485.    }
  486.  
  487.       break;
  488.  
  489.     default:
  490.       return;
  491.       break;
  492.     }
  493.  
  494.   UnlockLine (BlockPtr, LinePtr, &(Document->hCurTopScBlock),
  495.          &(Document->TopScOffset), &(Document->TopScLineID));
  496.  
  497. }
  498.  
  499.  
  500.  
  501. /*--- function HScrollIt ----------------------------------------------
  502.  *
  503.  *  Perform a horizontal scrolling action.
  504.  *
  505.  *    Entry    Document points to a document
  506.  *             wParam   is the wParam argument given from a WM_HSCROLL
  507.  *                      window message.  (One of the SB_ symbols.)
  508.  *             lParam   is the lParam argument (scroll box position).
  509.  */
  510. void
  511. HScrollIt (Document, wParam, lParam)
  512.      TypDoc *Document;
  513.      WPARAM wParam;
  514.      LPARAM lParam;
  515.  
  516. switch (LOWORD(wParam))
  517.   {
  518.   
  519.   case SB_LINEUP:
  520.     if(Document->ScXOffset > 0)
  521.     { 
  522.       RECT Rect;
  523.       
  524.       Document->ScXOffset--;          
  525.       Rect.top = 0;
  526.       Rect.bottom = Document->ScYHeight; 
  527.       
  528.       if(Document->DocType == DOCTYPE_ARTICLE)
  529.       {
  530.         Rect.left = -((int)ArtCharWidth + 1);
  531.       }
  532.       else
  533.       {
  534.         Rect.left = -((int)CharWidth + 1);
  535.       }    
  536.       Rect.right = Document->ScXWidth - Rect.left;  
  537.       ScrollWindow(Document->hDocWnd, -Rect.left, 0, &Rect, NULL);
  538.       Rect.right = -Rect.left;  
  539.  
  540.       InvalidateRect(Document->hDocWnd, &Rect, FALSE);
  541.     }
  542.     break;
  543.  
  544.   case SB_LINEDOWN:
  545.     if(Document->ScXOffset < Document->LongestLine - Document->ScXChars)
  546.     { 
  547.       RECT Rect;
  548.       
  549.       Document->ScXOffset++; 
  550.       Rect.top = 0;
  551.       Rect.bottom = Document->ScYHeight; 
  552.       
  553.       if(Document->DocType == DOCTYPE_ARTICLE)
  554.       {
  555.         Rect.left = ArtCharWidth + 1;  
  556.       }
  557.       else
  558.       {
  559.         Rect.left = CharWidth +1;
  560.       }    
  561.       Rect.right =  Document->ScXWidth + Rect.left;
  562.       ScrollWindow(Document->hDocWnd, -Rect.left, 0, &Rect, NULL);
  563.       Rect.right = Rect.left;
  564.       Rect.left = 0;    
  565.  
  566.       InvalidateRect(Document->hDocWnd, &Rect, FALSE);
  567.     }
  568.     break;                  
  569.   
  570.   case SB_PAGEUP:
  571.     if(((int)Document->ScXOffset - (int)Document->ScXChars) > 0)
  572.     {
  573.       Document->ScXOffset = Document->ScXOffset -
  574.                             Document->ScXChars + 5;
  575.     }
  576.     else
  577.     {
  578.       Document->ScXOffset = 0;
  579.     }
  580.     InvalidateRect(Document->hDocWnd, NULL, FALSE);
  581.     break;
  582.           
  583.   case SB_PAGEDOWN:
  584.     if((Document->ScXOffset + Document->ScXChars) < 
  585.        (Document->LongestLine - Document->ScXChars))
  586.     {
  587.       Document->ScXOffset = Document->ScXOffset +
  588.                             Document->ScXChars - 5;                            
  589.     }
  590.     else
  591.     {
  592.       Document->ScXOffset = Document->LongestLine - 
  593.                             Document->ScXChars;
  594.     }                                          
  595.     InvalidateRect(Document->hDocWnd, NULL, FALSE);
  596.     break;
  597.   
  598.   case SB_THUMBPOSITION:
  599.   case SB_THUMBTRACK:
  600.  
  601. #ifdef _WIN32
  602.     Document->ScXOffset = (int)HIWORD(wParam);
  603. #else
  604.     Document->ScXOffset = LOWORD(lParam);
  605. #endif
  606.  
  607.  
  608.     InvalidateRect (Document->hDocWnd, NULL, FALSE);
  609.     break;
  610.  
  611.   default:         
  612.     return;
  613.     break;
  614.       
  615.   }
  616. }
  617.  
  618.  
  619.  
  620.  
  621. /*--- function LineOnScreen ----------------------------------------
  622.  *
  623.  *  Determine whether a given line is displayed on the screen.
  624.  *  If it is, give the ordinal line number on the screen.
  625.  *
  626.  *  Entry   Doc         points to the document.
  627.  *          hTargBlock  is the handle of the block containing the line.
  628.  *          TargOffset  is the offset of the target line.
  629.  *          TargLineID  is the line's ID.
  630.  *
  631.  *  Exit    returns -1 if the line is not on the screen, else
  632.  *          the ordinal line number (0 = top line, etc.)
  633.  */
  634. int
  635. LineOnScreen (Doc, hTargBlock, TargOffset, TargLineID)
  636.      TypDoc *Doc;
  637.      HANDLE hTargBlock;
  638.      unsigned int TargOffset;
  639.      TypLineID TargLineID;
  640. {
  641.   TypBlock far *CurBlockPtr, far * TargBlockPtr;
  642.   TypLine far *CurLinePtr, far * TargLinePtr;
  643.   int iline;
  644.   BOOL found = FALSE, gotnext=TRUE;
  645.   HANDLE hBlock;
  646.   unsigned int Offset;
  647.   TypLineID MyLineID;
  648.  
  649.   LockLine (Doc->hCurTopScBlock, Doc->TopScOffset, Doc->TopScLineID, &CurBlockPtr, &CurLinePtr);
  650.   LockLine (hTargBlock, TargOffset, TargLineID, &TargBlockPtr, &TargLinePtr);
  651.  
  652.   for (iline = 0; gotnext && !found && (unsigned) iline < Doc->ScYLines;)
  653.     {
  654.       found = (TargLinePtr == CurLinePtr);
  655.       if(CurLinePtr->active) iline++;
  656.       if (!found)
  657.    {
  658.      gotnext = NextLine (&CurBlockPtr, &CurLinePtr);
  659.    }
  660.     }
  661.  
  662.   UnlockLine (CurBlockPtr, CurLinePtr, &hBlock, &Offset, &MyLineID);
  663.   UnlockLine (TargBlockPtr, TargLinePtr, &hBlock, &Offset, &MyLineID);
  664.  
  665.   if (!found)
  666.     iline = 0;
  667.   return (iline - 1);
  668. }
  669.  
  670. /*--- function NextWindow ----------------------------------------------
  671.  *
  672.  *  Makes another window the active window with input focus.
  673.  *  This function would typically be used to implement a keystroke
  674.  *  (usually F6) that switches windows.
  675.  *
  676.  *    Entry    Doc   points to the current document.
  677.  */
  678. void
  679. NextWindow (Doc)
  680.      TypDoc *Doc;
  681. {
  682.   int idoc;
  683.   int trydoctype;
  684.   TypDoc *NewDoc;
  685.  
  686.   /* First, locate the current window in our data structures.       */
  687.  
  688.   switch (Doc->DocType)
  689.     {
  690.     case DOCTYPE_NET:
  691.       idoc = 0;
  692.       trydoctype = DOCTYPE_GROUP;
  693.       break;
  694.     case DOCTYPE_GROUP:
  695.       for (idoc = 0; idoc < MAXGROUPWNDS && Doc != &(GroupDocs[idoc]); idoc++);
  696.       if (idoc >= MAXGROUPWNDS)
  697.    {
  698.      MessageBox (Doc->hDocWnd, "Error finding next window", "System error", MB_ICONHAND | MB_OK);
  699.    }
  700.       trydoctype = DOCTYPE_GROUP;
  701.       idoc++;
  702.       break;
  703.     case DOCTYPE_ARTICLE:
  704.       for (idoc = 0; idoc < MAXARTICLEWNDS && Doc != &(ArticleDocs[idoc]); idoc++);
  705.       if (idoc >= MAXARTICLEWNDS)
  706.    {
  707.      MessageBox (Doc->hDocWnd, "Error finding next window", "System error", MB_ICONHAND | MB_OK);
  708.    }
  709.       trydoctype = DOCTYPE_ARTICLE;
  710.       idoc++;
  711.       break;
  712.     }
  713.  
  714.   /* Now, find the next window in the sequence.                     */
  715.  
  716.   if (trydoctype == DOCTYPE_GROUP)
  717.     {
  718.       for (; idoc < MAXGROUPWNDS; idoc++)
  719.    {
  720.      if (GroupDocs[idoc].InUse)
  721.        {
  722.          NewDoc = ActiveGroupDoc = &(GroupDocs[idoc]);
  723.          goto foundit;
  724.        }
  725.    }
  726.       idoc = 0;
  727.     }
  728.  
  729.   /* Not found yet--try to find an Article doc.                     */
  730.  
  731.   for (; idoc < MAXARTICLEWNDS; idoc++)
  732.     {
  733.       if (ArticleDocs[idoc].InUse)
  734.    {
  735.      NewDoc = ActiveArticleDoc = &(ArticleDocs[idoc]);
  736.      goto foundit;
  737.    }
  738.     }
  739.  
  740.   /* Still not found--just make the Net document the next one.      */
  741.  
  742.   NewDoc = &NetDoc;
  743.  
  744. foundit:;
  745.  
  746.   SetActiveWindow (NewDoc->hDocWnd);
  747.   SetFocus (NewDoc->hDocWnd);
  748.  
  749. }
  750.  
  751. /*--- function AdjustScTop -----------------------------------
  752.  *
  753.  *  Adjust the top line of the screen so that a given line is sure
  754.  *  to appear on the screen.
  755.  *  Don't do anything if the document is one screen's length or smaller.
  756.  *
  757.  *    Entry
  758.  *             BlockPtr and LinePtr  point to the line we want to
  759.  *                      make sure is visible.
  760.  *
  761.  *    Exit     Doc's TopSc fields have been set to ensure that
  762.  *               the line will appear on the screen.
  763.  *             The line has been unlocked.
  764.  */
  765.  
  766. void
  767. AdjustTopSc (BlockPtr, LinePtr)
  768.      TypBlock far *BlockPtr;
  769.      TypLine far *LinePtr;
  770. {
  771.   unsigned int lineord;
  772.   TypDoc *Doc;
  773.   HANDLE hBlock;
  774.   unsigned int Offset;
  775.   TypLineID MyLineID;
  776.  
  777.   Doc = BlockPtr->OwnerDoc;
  778.   if (Doc->TotalLines > Doc->ScYLines)
  779.   //if (Doc->ActiveLines > Doc->ScYLines)  //??
  780.     {
  781.       lineord = WhatLine (BlockPtr, LinePtr);
  782.  
  783.       while (lineord > Doc->TotalLines - Doc->ScYLines)
  784.       //while (lineord > Doc->ActiveLines - Doc->ScYLines)  //??
  785.    {
  786.      PrevLine (&BlockPtr, &LinePtr);
  787.      lineord--;
  788.    }
  789.       Doc->TopLineOrd = lineord;
  790.       UnlockLine (BlockPtr, LinePtr, &(Doc->hCurTopScBlock),
  791.         &(Doc->TopScOffset), &(Doc->TopScLineID));
  792.     }
  793.   else
  794.     {
  795.       UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  796.     }
  797. }
  798.  
  799. /*
  800.  * This is a Doc/line-index version of AdjustScTop
  801.  * Don't you wish we could overload the function?!
  802.  * JSC 8/13/94
  803.  */
  804. void
  805. AdjustTopScByDoc (TypDoc *aDoc, unsigned int index)
  806. {
  807.     if (aDoc->TotalLines < aDoc->ScYLines ||
  808.        index >= aDoc->TopLineOrd && index < aDoc->TopLineOrd + aDoc->ScYLines)
  809.         return;        // already on screen
  810.     
  811.     if (index <= aDoc->ScYLines/2)
  812.         aDoc->TopLineOrd = 0;
  813.     else
  814.         aDoc->TopLineOrd = index - aDoc->ScYLines/2;    // center it
  815.  
  816.     InvalidateRect(aDoc->hDocWnd, NULL, FALSE);
  817. }
  818.  
  819. /*--- function ScreenToTop -------------------------------------
  820.  *
  821.  *  Sets a document so that the screen is scrolled to the top.
  822.  *
  823.  *  Entry   Doc     points to the document.
  824.  *
  825.  *  Exit    The document has been set to display starting at
  826.  *            the first line.
  827.  */
  828.  
  829. void
  830. ScreenToTop (TypDoc * Doc)
  831.   TypBlock far *BlockPtr;
  832.   TypLine far *LinePtr;
  833.   
  834.   Doc->hCurTopScBlock = Doc->hFirstBlock;
  835.   Doc->TopScOffset = sizeof (TypBlock);
  836.   Doc->TopScLineID = 0;
  837.   Doc->TopLineOrd = 0;
  838.   
  839.   LockLine(Doc->hFirstBlock,Doc->TopScOffset,Doc->TopScLineID,&BlockPtr,&LinePtr);
  840.   AdvanceToActive(&BlockPtr,&LinePtr);
  841.   UnlockLine(BlockPtr,LinePtr,&(Doc->hFirstBlock),&(Doc->TopScOffset),&(Doc->TopScLineID));
  842. }   
  843.  
  844. /*--- function AdvanceToActive ---------------------------------------
  845.  *
  846.  *  Advances a block/line pointer pair to an active line.
  847.  *  The pointers are unchanged if the current line is active.
  848.  *
  849.  *  Entry:  BlockPtr, LinePtr points to a line.
  850.  *
  851.  *  Exit:   BlockPtr,LinePtr  points to an active line, if possible.
  852.  *          Returns TRUE if successful, else FALSE if no line from
  853.  *            this point to the end of the document was active.
  854.  */
  855. BOOL
  856. AdvanceToActive(BlockPtr, LinePtr)
  857.      TypBlock far **BlockPtr;
  858.      TypLine far **LinePtr;
  859. {
  860.    BOOL ok=TRUE;
  861.    
  862.    while(!((*LinePtr)->active)) {
  863.       if(!NextLine(BlockPtr,LinePtr)) {
  864.          ok = FALSE;
  865.          break;
  866.       }
  867.    }   
  868.    
  869.    return ok;
  870. }
  871.  
  872.  
  873. /*--- function SetHandleBkBrush ---------------------------------------
  874.  *
  875.  *  Sets a new handle of a background brush.
  876.  *  This uses SetClassWord in a portable way and makes code look tidier.
  877.  *
  878.  *  Entry:  hwnd     Identifies window whose brush is to be changed.
  879.  *            handle    Handle to the new brush.
  880.  *
  881.  */
  882. void SetHandleBkBrush(HWND hwnd, HBRUSH handle)
  883. {
  884.     #ifdef _WIN32
  885.       SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG)handle);
  886.     #else
  887.       SetClassWord(hwnd, GCW_HBRBACKGROUND, (WORD)handle);
  888.     #endif
  889. }
  890.  
  891.  
  892. /*-- Last Line of WVSCREEN.C ----------------- */
  893.